class WebSocketService {
  constructor(url) {
    this.url = url
    this.ws = null
    this.lockReconnect = false
    this.heartbeatInterval = 30000; // 心跳间隔时间（毫秒）
    this.reconnectTimeout = 5000; // 自动重连间隔（毫秒）
    this.eventListeners = {}
  }

  connect() {
    if (!this.url) return

    this.ws = new WebSocket(this.url)

    this.ws.onopen = () => {
      console.log('[WebSocket] 已连接')
      this.startHeartbeat()
    }

    this.ws.onmessage = (msg) => {
      try {
        const data = JSON.parse(msg.data)
        this.dispatch(data.type, data.payload)
      } catch (e) {
        console.warn('[WebSocket] 非 JSON 消息', msg.data)
      }
    }

    this.ws.onclose = () => {
      console.log('[WebSocket] 连接关闭，准备重连...')
      this.reconnect()
    }

    this.ws.onerror = () => {
      console.log('[WebSocket] 连接错误')
      this.reconnect()
    }
  }

  reconnect() {
    if (this.lockReconnect) return
    this.lockReconnect = true
    clearTimeout(this.reconnectTimeout)
    this.reconnectTimeout = setTimeout(() => {
      this.connect()
      this.lockReconnect = false
    }, this.reconnectTimeout)
  }

  startHeartbeat() {
    clearInterval(this.heartbeatInterval)
    this.heartbeatInterval = setInterval(() => {
       this.send({type: 'heartbeat'})
    }, this.heartbeatInterval)
  }

  send(data) {
    if (this.ws && this.ws.readyState === WebSocket.OPEN) {
      this.ws.send(JSON.stringify(data))
    } else {
      console.warn('[WebSocket] 当前不可发送消息')
    }
  }

  close() {
    clearInterval(this.heartbeatInterval)
    this.ws && this.ws.close()
  }

  // 注册监听
  on(eventType, callback) {
    if (!this.eventListeners[eventType]) {
      this.eventListeners[eventType] = []
    }
    this.eventListeners[eventType].push(callback)
  }

  // 取消监听
  off(eventType, callback) {
    if (!this.eventListeners[eventType]) return
    this.eventListeners[eventType] = this.eventListeners[eventType].filter(fn => fn !== callback)
  }

  dispatch(eventType, payload) {
    if (!this.eventListeners[eventType]) return
    this.eventListeners[eventType].forEach(fn => fn(payload))
  }
}

const socket = new WebSocketService(process.env.VUE_APP_WS_URL || 'wss://thinkphp8.jiarong.net.cn/wss')
export default socket
